import Head from 'next/head';
import RootPropTable from '../../../components/prop-tables/RootPropTable';
import ColumnOptionsTable from '../../../components/prop-tables/ColumnOptionsTable';
import ThemeExample from '../../../examples/mui-theme';
import CustomizeStylesExample from '../../../examples/customize-table-styles';
import { Box } from '@mui/material';

<Head>
  <title>
    {'Customize (Style) Components Guide - Material React Table V1 Docs'}
  </title>
  <meta
    name="description"
    content="How to customize and pass props to Material UI components and set up a Material UI Theme in Material React Table"
  />
</Head>

## Customize (Style) Components Guide

One of the strengths of Material React Table is that it exposes a majority of all the underlying Material UI component props used to build the table.

Additionally, in one of the sections below, you will learn [how to customize and use a Material UI Theme](#material-ui-theme) to customize colors, typography, or any other default CSS that is used by Material React Table.

### Relevant Props

All props labeled `mui...Props` get forwarded to Material UI components. Here is a list of all the props that are exposed in both the root props and column options.

<RootPropTable
  onlyProps={
    new Set([
      'muiBottomToolbarProps',
      'muiExpandAllButtonProps',
      'muiExpandButtonProps',
      'muiLinearProgressProps',
      'muiSearchTextFieldProps',
      'muiSelectAllCheckboxProps',
      'muiSelectCheckboxProps',
      'muiTableBodyCellCopyButtonProps',
      'muiTableBodyCellEditTextFieldProps',
      'muiTableBodyCellProps',
      'muiTableBodyCellSkeletonProps',
      'muiTableBodyProps',
      'muiTableBodyRowDragHandleProps',
      'muiTableBodyRowProps',
      'muiTableContainerProps',
      'muiTableDetailPanelProps',
      'muiTableFooterCellProps',
      'muiTableFooterProps',
      'muiTableFooterRowProps',
      'muiTableHeadCellColumnActionsButtonProps',
      'muiTableHeadCellDragHandleProps',
      'muiTableHeadCellFilterTextFieldProps',
      'muiTableHeadCellProps',
      'muiTableHeadProps',
      'muiTableHeadRowProps',
      'muiTablePaginationProps',
      'muiTablePaperProps',
      'muiTableProps',
      'muiToolbarAlertBannerChipProps',
      'muiToolbarAlertBannerProps',
      'muiTopToolbarProps',
    ])
  }
/>

### Relevant Column Options

Some of the column options expose the same props as above, but on a per column basis.

<ColumnOptionsTable
  onlyProps={
    new Set([
      'muiTableBodyCellCopyButtonProps',
      'muiTableBodyCellEditTextFieldProps',
      'muiTableBodyCellProps',
      'muiTableFooterCellProps',
      'muiTableHeadCellColumnActionsButtonProps',
      'muiTableHeadCellFilterTextFieldProps',
      'muiTableHeadCellProps',
    ])
  }
/>

### Material UI Props and Types

Each prop can either be passed as an object or as a callback function where you get access to the underlying `table` instance and any other relevant callback parameters, such as `cell`, `row`, `column`, etc. This lets you easily run conditional logic on the props you pass. Let's take a look at a few examples.

> All `mui...Props` props are strongly typed and you should get ts hints as you write them. API docs are available on the [Material UI website](https://mui.com/material-ui/api/table/) for each component.

#### Static Prop Objects

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableRowSelection
  //passing the static object variant if no dynamic logic is needed
  muiSelectCheckboxProps={{
    color: 'secondary', //makes all checkboxes use the secondary color
  }}
/>
```

#### Callback Functions to Dynamically Set Prop Values

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  enableRowSelection
  //passing the callback function variant. (You should get type hints for all the callback parameters available)
  muiSelectCheckboxProps={({ row }) => ({
    color: 'secondary',
    disabled: row.original.isAccountLocked, //access the row data to determine if the checkbox should be disabled
  })}
/>
```

### Styling Material UI Components

Each `mui...Prop` has multiple options for you to add styling to the component. You could simply pass `className` or `style` props to any `mui...Props` prop, but there is also the `sx` prop...which totally rocks!

> Hint: You should just use the `sx` prop for all styling instead of `className` or `style` props.

#### The SX Prop

The recommended way to style Material UI components in Material React Table will be the [`sx` prop](https://mui.com/system/basics/#the-sx-prop) throughout this docs site, as it is both the most simple and the most powerful way to style Material UI components as of Material UI V5. They can work and be as simple as a `style` prop, but behind the scenes, they work more like emotion styled-components by using `mui/system`.

Don't worry, `className` and `style` props will still work, but let's show off some of the more elegant syntax you can use with the `sx` prop.

1. The `sx` prop can be used just a simply as a `style` prop by default

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTableHeadCellProps={{
    //simple styling with the `sx` prop, works just like a style prop in this example
    sx: {
      fontWeight: 'normal',
      fontSize: '14px',
    },
  }}
/>
```

2. The `sx` prop gets easy access to your _muiTheme_ without you having to call the theme from a `useTheme` hook.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTableHeadCellProps={{
    //no useTheme hook needed, just use the `sx` prop with the theme callback
    sx: (theme) => ({
      color: theme.palette.text.secondary,
    }),
  }}
/>
```

3. The `sx` prop gives you a much more concise way to add media queries to your styling.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTableHeadCellProps={{
    //easier way to create media queries, no useMediaQuery hook needed.
    sx: {
      fontSize: {
        xs: '10px',
        sm: '11px',
        md: '12px',
        lg: '13px',
        xl: '14px',
      },
    },
  }}
/>
```

There are many more advantages to using the `sx` prop, but that is all we will discuss in these docs. You can learn more about it the official [Material UI Docs](https://mui.com/system/getting-started/the-sx-prop/).

### Material UI Theme

Material React Table respects your Material UI Theme. If you have already set up Material UI and a global Material UI Theme, you should already be set. But if you have not, you should visit the offical [Material UI Theming Docs](https://mui.com/material-ui/customization/theming/) to learn how to set that up.

```jsx
function App() {
  //Have you setup your Mui Theme globally in your app root?
  return (
    <ThemeProvider theme={createTheme({...})}>
      ...rest of your application
    </ThemeProvider>
  );
}
```

#### Customize Theme Just for your Table

Thanks to Material UI allowing you to [nest multiple Theme Providers](https://mui.com/material-ui/customization/theming/#nesting-the-theme), you can change your Material UI Theme just for the `<MaterialReactTable />` component by wrapping a `<ThemeProvider theme={createTheme(...)}>` around just your table. The values in this theme will only effect the `<MaterialReactTable />` component, and not the rest of your site. It will also inherit values from your global theme, so you do not have to redefine everything again. You can just tweak the values you want to change.

```jsx
import { createTheme, ThemeProvider } from '@mui/material';
//in one of your normal components
return (
  <ThemeProvider theme={createTheme({...})}>
    <MaterialReactTable columns={columns} data={data} />
  </ThemeProvider>
);
```

#### Important Theme Values used by Material React Table

`<MaterialReactTable />` will primarily use the following values internally from your Material UI Theme by default:

- `theme.palette.background.default` - used as the background color for most table components by default
- `theme.palette.divider` - used in dividers in menus and for the column resizing handle
- `theme.palette.info.main` - used in the Toolbar Alert Banner and the Toolbar DropZone component
- `theme.palette.primary.main` - used as the primary color for anything colorful in the table (input fields, checkboxes, dragging borders, etc.)

Notice that by default, the <Box component="span" sx={{color: "secondary.main", display: 'inline'}}>secondary color</Box> isn't used at all. Remember though that you can always override which color a component uses by passing in a `mui...Props` prop, like how we changed checkboxes to use the secondary color in the [example above](#static-prop-objects).

#### Custom Material UI Theme Example

A common use case for this could be if you want to switch your primary and secondary colors, just for this table. Let's take a look at an example that does that, along with some other styling tweaks, so that we can make an ugly table.

<ThemeExample />

### Customize Table Paper Styling

You can customize both the props and the styles of the internal `<Paper />` component that wraps the table by passing in a `muiTablePaperProps` prop. This is useful if you want to change the elevation of the paper, or add a border radius, or any other styling you want to do to the paper.

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTablePaperProps={{
    elevation: 0, //change the mui box shadow
    //customize paper styles
    sx: {
      borderRadius: '0',
      border: '1px dashed #e0e0e0',
    },
  }}
/>
```

### Customize Table Body, Rows, Columns, and Cells

#### Stripe Rows Example

If you need to style many of the rows or columns in a consistent manner, it usually makes sense to style the `<TableBody />` component itself. For example if you want to stripe the rows, you can do something like this:

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTableBodyProps={{
    sx: {
      //stripe the rows, make odd rows a darker color
      '& tr:nth-of-type(odd)': {
        backgroundColor: '#f5f5f5',
      },
    },
  }}
/>
```

#### Stripe Columns Example

Similarly, if you want to stripe the columns, you can do something like this:

```jsx
<MaterialReactTable
  columns={columns}
  data={data}
  muiTableBodyProps={{
    sx: {
      //stripe the rows, make odd rows a darker color
      '& td:nth-of-type(odd)': {
        backgroundColor: '#f5f5f5',
      },
    },
  }}
  muiTableBodyCellProps={{
    sx: {
      borderRight: '2px solid #e0e0e0', //add a border between columns
    },
  }}
/>
```

<CustomizeStylesExample />
